package com.laviedesfons.jhmtasc.types.abstracts;

import com.laviedesfons.jhmtasc.exceptions.MException;
import com.laviedesfons.jhmtasc.metadata.MetaField;
import com.laviedesfons.jhmtasc.metadata.MetaField.Kind;
import com.laviedesfons.jhmtasc.types.interfaces.InternalType;
import fr.x9c.cadmium.kernel.Block;
import fr.x9c.cadmium.kernel.Value;

/**
 *
 * @author Romano
 */
public abstract class Interface<T extends InternalType> extends AbstractType<T> {

    private int id = -1;

    @Override
    public InternalType fromValue(Value v) throws MException {

        MetaField field = getField(v);
        if((v.isBlock() && field.getKind() == Kind.VALUE)
                || v.isLong() && field.getKind() == Kind.OFFSET){

            id = field.getId();
            flag = field.getFlag();

            if( v.isBlock() && v.asBlock().sizeValues() == 1){
                v = v.asBlock().get(0);
            }

            wrapped = (T) field.getMetaType().create().fromValue(v);

            if(getMetaModel().isRootType()){
                return wrapped;
            }
            return this;
        }
        throw new MException("unable to create type from value - "+field);
    }

    @Override
    public Value toValue() {
        if (wrapped != null) {
            if (getMetaModel().isRootType()) {
                return wrapped.toValue();
            } else {
                return Value.createFromBlock(
                        Block.createBlock(id, wrapped.toValue()));
            }
        } else {
            return Value.createFromLong(id);
        }
    }
}